<template>
	<div class="real-time-broadcast">
		<div class="box-left">
			<el-radio-group
				v-model="microphone"
				class="radio-position"
			>
				<el-radio  label="local" class="radio-item">
					<span class="el-icon-microphone microphone-icon"></span>
                    <span class="label" title="本机设备">本机设备</span>
                </el-radio>
			</el-radio-group>
		</div>
		<!-- 实时语音 -->
		<div class="box-right">
            <div class="real-time-status">
                <p :class="realTimePlay?'danger-color':'primary-color'">{{realTimePlay ? '广播中' : '未广播'}}</p>
                <p>
                    <span 
                        class="video-icon"
                        :class="realTimePlay ? 'el-icon-video-pause':'el-icon-video-play'"
                        @click="changeStatus(realTimePlay?'stop':'start')"
                    ></span>
                </p>
                <p>{{realTimePlay ? '点击停止广播' : '点击开始广播'}}</p>
            </div>
            <!-- <canvas id="casvased" style="width: 200px;height: 50px"></canvas> -->
            <div class="real-time-volume">
                <span>音量: {{realTimeVolume}}</span>
                <el-slider
                    :min="0"
                    :max="15"
                    :step="1"
                    @change="changeVolume"
                    class="volume-slider"
                    v-model="realTimeVolume"
                ></el-slider>
            </div>
        </div>
	</div>
</template>

<script>
import Api from "./api";
import MP3Recorder from "jsmod/recordmp3";
export default {
	data() {
		return {
			microphone: 'local', // 选中麦克风
            realTimePlay: false, // 实时广播是否播放中
            realTimeVolume: 5, // 实时语音音量
            localRecordId: '', // 广播下发信息id（链接websocket时需要传这个参数作为唯一标识符）有效期30分钟
            ws: null, // websocket实例
            recorder: null,
            reader: null,
        };
	},
	methods: {
        // 改变广播状态
        changeStatus(type) {
            // start 开始  stop 停止 volume调整声音
            if (type === 'start') {
                this.start();
            } else if (type === 'stop') {
                this.stop();
            }
        },
        // 开始广播
        start() {
            if (!this.microphone) {
                Message.error('请先选择麦克风设备')
                return;
            }
            // 获取广播下发信息id（链接websocket时需要传这个参数作为唯一标识符）有效期30分钟
            // 开始本机录音设备实时广播
            const res = await Api.localBroadcast({
                deviceLists: this.selectIds
            })
            if (+res.code === 200) {
                this.realTimePlay = true;
                this.localRecordId = res?.data || '';
                this.initWs();
            } else {
                Message.error(res.message || res.msg || '开始广播失败')
            }
        },
        
        // 暂停广播
        async stop() {
            // 本机广播
            if (this.microphone === 'local') {
                this.stopRecBroadcast();
            } else {
                this.stopMicBroadcast();
            }
        },
        // 暂停麦克风设备实时广播
        async stopMicBroadcast() {
            const res = await Api.stopMicBroadcast({
                data: {
                    realExeDevIdList: this.selectIds
                }
            })
            if (+res.code === 200) {
                this.realTimePlay = false;
            } else {
                Message.error(res.message || res.msg || '暂停广播失败')
            }
        },
        // 暂停本机录音设备实时广播
        async stopRecBroadcast() {
            if (this.ws) {
                this.recorder?.stop?.();
                this.recorder = null;
                if (this.ws.readyState === this.ws.OPEN) {
                    this.ws.send(JSON.stringify({ action: '0'}));
                    this.ws.close();
                }
                console.log('关闭对讲以及WebSocket');
                this.realTimePlay = false;
            }
        },
        // 切换音量
        async changeVolume() {
            // 播放中，调接口实时切换
            if (this.realTimePlay) {
                let res = await Api.setDeviceVolume({
                    data: {
                        broadcastIdList: this.selectIds,
                        volume: this.realTimeVolume,
                    },
                });
                if (+res.code === 200) {
                    // Message.success("修改音量成功");
                } else {
                    Message.error(res.message || res.msg || '修改音量失败');
                }
            }
        },
        // 初始化ws
        initWs() {
            if (this.ws && this.ws.readyState === this.ws.OPEN) {
                this.ws?.close?.();
            }
            this.ws = new WebSocket(`${GlobalConfig.localRecordWsUrl()}/${this.localRecordId}`);
            // this.ws = new WebSocket(`ws://10.10.2.165:8180/recordingWsHandler/${this.localRecordId}`);
            this.ws.binaryType = 'arraybuffer';
            this.ws.onopen = () => {
                console.log('握手成功');
                console.log(this.ws, 'this.ws');
                if (this.ws.readyState === this.ws.OPEN) { 
                    //ws进入连接状态, 初始化readerFile, 初始化录音
                    this.initReader();
                    this.initRecord();
                }
            };
            this.ws.onmessage = function (msg) {
                console.info(msg)
            }
            this.ws.onerror = function (err) {
                console.info(err)
                this.realTimePlay = false;
            }
        },
        // 初始化recorder
        initRecord() {
            // const canvas = document.getElementById("casvased");
            // const canvasCtx = canvas.getContext("2d")
            this.recorder = new MP3Recorder({
                debug: true,
                // canvasWidth: 400,
                // canvasHeight: 100,
                // canvasCtx: canvasCtx,
                funOk: ()=> {
                    console.log('初始化成功');
                    this.recorder?.start?.();
                    this.recorder?.draw?.();
                    this.realTimePlay = true;
                },
                funCancel: (msg)=> {
                    this.recorder = null;
                    this.ws?.close?.();
                    this.realTimePlay = false;
                    Message.error(`录音开启失败：${msg}`);
                },
                funAudioprocess: this.sentData
            });
        },
        // 初始化FileReader
        initReader() { 
            //对以获取的数据进行处理(分包)
            this.reader = new FileReader();
            const _this = this;
            this.reader.onload = e => {
                let outbuffer = e.target.result;
                let arr = new Int8Array(outbuffer);
                if (arr.length > 0) {
                    let tmparr = new Int8Array(1024);
                    let j = 0;
                    for (let i = 0; i < arr.byteLength; i++) {
                        tmparr[j++] = arr[i];
                        if (((i + 1) % 1024) == 0) {
                            //ws处于连接状态
                            if (_this.ws?.readyState == 1) { 
                                _this.ws?.send?.(tmparr);
                            }
                            if (arr.byteLength - i - 1 >= 1024) {
                                tmparr = new Int8Array(1024);
                            } else {
                                tmparr = new Int8Array(arr.byteLength - i - 1);
                            }
                            j = 0;
                        }
                        if ((i + 1 == arr.byteLength) && ((i + 1) % 1024) != 0) {
                            //ws处于连接状态
                            if (_this.ws?.readyState == 1) { 
                                _this.ws?.send?.(tmparr);
                            }
                        }
                    }
                }
            };
        },
        // 发送音频流
        sentData() { //对以获取的数据进行处理(分包)
            this.recorder?.getMp3Blob?.((blob) => {
                this.reader?.readAsArrayBuffer?.(blob);//这里拿到mp3格式的音频流写入到reader中       
            })
        },
	},
    beforeDestroy() {
        if (this.realTimePlay) {
            this.stop();
        }
    }
};
</script>

<style lang='less' scoped>
@deep: ~'>>>';
.real-time-broadcast {
    display: flex;
    .box-left {
            width: 180px;
            max-height: 300px;
            overflow: auto;
            padding: @side-gap-small;
            border-right: 1px solid @border-color-primary;
            .box-title {
                color: @color-primary;
            }
            .radio-position {
                display: flex;
                flex-direction: column;
                margin-top: @side-gap-small;
                max-height: 300px;
                overflow: auto;
                .radio-item {
                    margin: 5px 0;
                    .label {
                        display: inline-block;
                        max-width: 120px;
                        white-space: nowrap;
                        overflow: hidden;
                        text-overflow: ellipsis;
                        line-height: 14px;
                    }
                    .microphone-icon {
                        font-size: @font-size-medium;
                        color: @color-primary;
                        line-height: 14px;
                    }
                    @{deep} {
                        .el-radio__input {
                            line-height: 20px;
                        }
                    }
                }
            }
    }
    .box-right {
            flex: 1;
            display: flex;
            flex-direction: column;
            .real-time-status {
                flex: 1;
                text-align: center;
                padding: 40px 0;
                display: flex;
                flex-direction: column;
                justify-content: center;
                .video-icon {
                    font-size: 80px;
                    margin: @side-gap-small 0;
                    cursor: pointer;
                }
                .el-icon-video-pause {
                    color: @color-danger;
                }
                .el-icon-video-play {
                    color: @color-primary;
                }
            }

            .real-time-volume {
                border-top: 1px solid @border-color-primary;
                padding: @side-gap-small;
                display: flex;
                line-height: 38px;
                .volume-slider {
                    flex: 1;
                    margin-left: @side-gap-small;;
                }
            }
    }
}
.primary-color {
    color: @color-primary;
}
.danger-color {
    color: @color-danger;
}
</style>
